﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http.SelfHost;
using System.Web.Http;
using System.ServiceModel;
using System.Net;
using System.IdentityModel.Selectors;
using System.ServiceModel.Channels;
using System.Web.Http.SelfHost.Channels;
using PServiceBus.Core.Runtime;

namespace PServiceBus.WebAPI {
    public class APIServer {

        private static HttpSelfHostServer _server;
        private static int _port;

        class HttpsSelfHostConfiguration : HttpSelfHostConfiguration {
            public HttpsSelfHostConfiguration(string baseAddress) : base(baseAddress) { }
            public HttpsSelfHostConfiguration(Uri baseAddress) : base(baseAddress) { }
            protected override BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding) {
                httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
                return base.OnConfigureBinding(httpBinding);
            }
        }

        public static void Start(int port, bool secured = false, string thumbprint = "", string appid = "") {
            var address = String.Format("http{1}://localhost:{0}", port,
                secured ? "s" : string.Empty);
            var config = secured ? new HttpsSelfHostConfiguration(address) :
                new HttpSelfHostConfiguration(address);
            _port = port;
            if (secured) {
                ShellHelper.NetShAddUrlAclAndSSL(port, thumbprint, appid);
            }

            config.Routes.MapHttpRoute("ClientAccessPolicy", "clientaccesspolicy.xml",
                new { controller = "File" });

            config.Routes.MapHttpRoute("Flash", "flash/{id}",
                new { controller = "Flash", id = RouteParameter.Optional });

            config.Routes.MapHttpRoute("Default", "{controller}/{action}/{id}",
                new { controller = "ESB", id = RouteParameter.Optional });

            config.TransferMode = TransferMode.Streamed;

            config.SendTimeout = TimeSpan.MaxValue;

            config.ReceiveTimeout = TimeSpan.MaxValue;

            config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

            config.Formatters.Insert(0, new JsonpMediaTypeFormatter());

            _server = new HttpSelfHostServer(config);
            _server.OpenAsync().Wait();
        }

        public static void Stop() {
            if (_server == null) return;
            try { _server.CloseAsync().Wait(); } catch { }
            ShellHelper.NetShRemoveUrlAcl(_port);
        }
    }
}
